/**
 * 表单验证工具类
 * 提供常用的表单验证功能和UI反馈
 */

class FormValidator {
    constructor(form, options = {}) {
        this.form = typeof form === 'string' ? document.querySelector(form) : form;
        this.options = {
            liveValidation: true,
            showErrorMessages: true,
            scrollOnError: true,
            validateOnBlur: true,
            ...options
        };
        
        this.rules = new Map();
        this.errors = new Map();
        this.validators = this.getDefaultValidators();
        
        this.init();
    }

    /**
     * 初始化验证器
     */
    init() {
        if (!this.form) {
            console.error('Form element not found');
            return;
        }

        // 解析表单字段验证规则
        this.parseValidationRules();

        // 绑定事件
        this.bindEvents();
    }

    /**
     * 获取默认验证器
     */
    getDefaultValidators() {
        return {
            required: (value) => {
                if (typeof value === 'string') {
                    return value.trim().length > 0;
                }
                return value !== null && value !== undefined;
            },
            
            email: (value) => {
                if (!value) return true;
                const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
                return emailRegex.test(value);
            },
            
            phone: (value) => {
                if (!value) return true;
                const phoneRegex = /^1[3-9]\d{9}$/;
                return phoneRegex.test(value.replace(/\s+/g, ''));
            },
            
            url: (value) => {
                if (!value) return true;
                try {
                    new URL(value);
                    return true;
                } catch {
                    return false;
                }
            },
            
            minLength: (value, min) => {
                if (!value) return true;
                return value.length >= min;
            },
            
            maxLength: (value, max) => {
                if (!value) return true;
                return value.length <= max;
            },
            
            pattern: (value, pattern) => {
                if (!value) return true;
                const regex = new RegExp(pattern);
                return regex.test(value);
            },
            
            numeric: (value) => {
                if (!value) return true;
                return !isNaN(parseFloat(value)) && isFinite(value);
            },
            
            integer: (value) => {
                if (!value) return true;
                return Number.isInteger(Number(value));
            },
            
            min: (value, min) => {
                if (!value) return true;
                return Number(value) >= min;
            },
            
            max: (value, max) => {
                if (!value) return true;
                return Number(value) <= max;
            },
            
            sameAs: (value, fieldName) => {
                const otherField = this.form.querySelector(`[name="${fieldName}"]`);
                return otherField && otherField.value === value;
            },
            
            custom: (value, validator) => {
                return validator(value);
            }
        };
    }

    /**
     * 解析验证规则
     */
    parseValidationRules() {
        const fields = this.form.querySelectorAll('input, select, textarea');
        
        fields.forEach(field => {
            const rules = [];
            
            // 从data属性解析规则
            const required = field.hasAttribute('required') || field.hasAttribute('data-required');
            const pattern = field.getAttribute('pattern');
            const minLength = field.getAttribute('minlength');
            const maxLength = field.getAttribute('maxlength');
            const min = field.getAttribute('min');
            const max = field.getAttribute('max');
            const type = field.type;
            
            if (required) {
                rules.push({ name: 'required', message: this.getErrorMessage(field, 'required') });
            }
            
            if (type === 'email') {
                rules.push({ name: 'email', message: this.getErrorMessage(field, 'email') });
            }
            
            if (type === 'tel') {
                rules.push({ name: 'phone', message: this.getErrorMessage(field, 'phone') });
            }
            
            if (type === 'url') {
                rules.push({ name: 'url', message: this.getErrorMessage(field, 'url') });
            }
            
            if (type === 'number') {
                rules.push({ name: 'numeric', message: this.getErrorMessage(field, 'numeric') });
                
                if (min !== null) {
                    rules.push({ 
                        name: 'min', 
                        value: Number(min), 
                        message: this.getErrorMessage(field, 'min', { min }) 
                    });
                }
                
                if (max !== null) {
                    rules.push({ 
                        name: 'max', 
                        value: Number(max), 
                        message: this.getErrorMessage(field, 'max', { max }) 
                    });
                }
            }
            
            if (pattern) {
                rules.push({ 
                    name: 'pattern', 
                    value: pattern, 
                    message: this.getErrorMessage(field, 'pattern') 
                });
            }
            
            if (minLength !== null) {
                rules.push({ 
                    name: 'minLength', 
                    value: Number(minLength), 
                    message: this.getErrorMessage(field, 'minLength', { min: minLength }) 
                });
            }
            
            if (maxLength !== null) {
                rules.push({ 
                    name: 'maxLength', 
                    value: Number(maxLength), 
                    message: this.getErrorMessage(field, 'maxLength', { max: maxLength }) 
                });
            }
            
            // 从data-validation属性解析自定义规则
            const validationAttr = field.getAttribute('data-validation');
            if (validationAttr) {
                try {
                    const customRules = JSON.parse(validationAttr);
                    customRules.forEach(rule => {
                        rules.push({
                            name: rule.name,
                            value: rule.value,
                            message: rule.message || this.getErrorMessage(field, rule.name)
                        });
                    });
                } catch (e) {
                    console.error('Invalid validation attribute:', validationAttr);
                }
            }
            
            if (rules.length > 0) {
                this.rules.set(field, rules);
            }
        });
    }

    /**
     * 获取错误消息
     */
    getErrorMessage(field, ruleName, params = {}) {
        // 优先使用自定义消息
        const customMessage = field.getAttribute(`data-error-${ruleName}`);
        if (customMessage) {
            return this.formatMessage(customMessage, params);
        }
        
        // 使用默认消息
        const fieldName = field.getAttribute('data-label') || field.name || '此字段';
        const messages = {
            required: `${fieldName}不能为空`,
            email: '请输入有效的邮箱地址',
            phone: '请输入有效的手机号码',
            url: '请输入有效的URL地址',
            numeric: '请输入有效的数字',
            integer: '请输入整数',
            minLength: `${fieldName}长度不能少于${params.min}个字符`,
            maxLength: `${fieldName}长度不能超过${params.max}个字符`,
            min: `${fieldName}不能小于${params.min}`,
            max: `${fieldName}不能大于${params.max}`,
            pattern: `${fieldName}格式不正确`,
            sameAs: '两次输入不一致'
        };
        
        return messages[ruleName] || `${fieldName}格式不正确`;
    }

    /**
     * 格式化消息
     */
    formatMessage(message, params) {
        return message.replace(/\{(\w+)\}/g, (match, key) => {
            return params[key] !== undefined ? params[key] : match;
        });
    }

    /**
     * 绑定事件
     */
    bindEvents() {
        // 表单提交事件
        this.form.addEventListener('submit', (e) => {
            if (!this.validate()) {
                e.preventDefault();
            }
        });

        // 实时验证
        if (this.options.liveValidation) {
            this.form.querySelectorAll('input, select, textarea').forEach(field => {
                if (this.rules.has(field)) {
                    field.addEventListener('input', window.uxUtils.debounce(() => {
                        this.validateField(field);
                    }, 300));
                }
            });
        }

        // 失焦验证
        if (this.options.validateOnBlur) {
            this.form.querySelectorAll('input, select, textarea').forEach(field => {
                if (this.rules.has(field)) {
                    field.addEventListener('blur', () => {
                        this.validateField(field);
                    });
                }
            });
        }
    }

    /**
     * 验证整个表单
     */
    validate() {
        let isValid = true;
        const fields = this.form.querySelectorAll('input, select, textarea');
        
        this.clearErrors();
        
        fields.forEach(field => {
            if (!this.validateField(field)) {
                isValid = false;
            }
        });
        
        if (!isValid && this.options.scrollOnError) {
            this.scrollToFirstError();
        }
        
        return isValid;
    }

    /**
     * 验证单个字段
     */
    validateField(field) {
        const rules = this.rules.get(field);
        if (!rules) return true;
        
        let isValid = true;
        const value = field.value;
        
        rules.forEach(rule => {
            const validator = this.validators[rule.name];
            if (!validator) return;
            
            let isValidRule;
            if (rule.value !== undefined) {
                isValidRule = validator(value, rule.value);
            } else {
                isValidRule = validator(value);
            }
            
            if (!isValidRule) {
                this.addError(field, rule.message);
                isValid = false;
            }
        });
        
        // 如果验证通过，清除该字段的错误
        if (isValid) {
            this.clearFieldError(field);
        }
        
        return isValid;
    }

    /**
     * 添加错误
     */
    addError(field, message) {
        this.errors.set(field, message);
        
        if (this.options.showErrorMessages) {
            this.showFieldError(field, message);
        }
        
        field.classList.add('border-red-500');
        field.setAttribute('aria-invalid', 'true');
    }

    /**
     * 显示字段错误
     */
    showFieldError(field, message) {
        // 移除之前的错误消息
        const existingError = field.parentNode.querySelector('.field-error');
        if (existingError) {
            existingError.remove();
        }
        
        const errorElement = document.createElement('p');
        errorElement.className = 'field-error text-red-500 text-sm mt-1';
        errorElement.textContent = message;
        
        // 根据字段类型插入错误消息
        if (field.type === 'checkbox' || field.type === 'radio') {
            const container = field.closest('div');
            if (container) {
                container.appendChild(errorElement);
            }
        } else {
            field.parentNode.appendChild(errorElement);
        }
    }

    /**
     * 清除字段错误
     */
    clearFieldError(field) {
        this.errors.delete(field);
        field.classList.remove('border-red-500');
        field.setAttribute('aria-invalid', 'false');
        
        const errorElement = field.parentNode.querySelector('.field-error');
        if (errorElement) {
            errorElement.remove();
        }
    }

    /**
     * 清除所有错误
     */
    clearErrors() {
        this.errors.clear();
        
        this.form.querySelectorAll('.border-red-500').forEach(field => {
            field.classList.remove('border-red-500');
            field.setAttribute('aria-invalid', 'false');
        });
        
        this.form.querySelectorAll('.field-error').forEach(error => {
            error.remove();
        });
    }

    /**
     * 滚动到第一个错误
     */
    scrollToFirstError() {
        const firstError = this.form.querySelector('.border-red-500');
        if (firstError) {
            firstError.scrollIntoView({ 
                behavior: 'smooth', 
                block: 'center' 
            });
            firstError.focus();
        }
    }

    /**
     * 获取验证错误
     */
    getErrors() {
        const errors = {};
        this.errors.forEach((message, field) => {
            errors[field.name] = message;
        });
        return errors;
    }

    /**
     * 添加自定义验证器
     */
    addValidator(name, validator, defaultMessage = null) {
        this.validators[name] = validator;
        
        if (defaultMessage) {
            this.defaultMessages = this.defaultMessages || {};
            this.defaultMessages[name] = defaultMessage;
        }
    }

    /**
     * 添加字段规则
     */
    addFieldRule(fieldName, rules) {
        const field = this.form.querySelector(`[name="${fieldName}"]`);
        if (field) {
            this.rules.set(field, rules);
        }
    }

    /**
     * 移除字段规则
     */
    removeFieldRule(fieldName) {
        const field = this.form.querySelector(`[name="${fieldName}"]`);
        if (field) {
            this.rules.delete(field);
        }
    }

    /**
     * 销毁验证器
     */
    destroy() {
        this.clearErrors();
        this.rules.clear();
        this.errors.clear();
    }
}

/**
 * 常用验证规则预设
 */
const ValidationPresets = {
    // 用户注册表单
    registration: {
        username: [
            { name: 'required', message: '用户名不能为空' },
            { name: 'minLength', value: 3, message: '用户名至少3个字符' },
            { name: 'maxLength', value: 20, message: '用户名最多20个字符' },
            { name: 'pattern', value: '^[a-zA-Z0-9_]+$', message: '用户名只能包含字母、数字和下划线' }
        ],
        email: [
            { name: 'required', message: '邮箱不能为空' },
            { name: 'email', message: '请输入有效的邮箱地址' }
        ],
        password: [
            { name: 'required', message: '密码不能为空' },
            { name: 'minLength', value: 6, message: '密码至少6个字符' },
            { name: 'maxLength', value: 20, message: '密码最多20个字符' }
        ],
        confirmPassword: [
            { name: 'required', message: '请确认密码' },
            { name: 'sameAs', value: 'password', message: '两次输入的密码不一致' }
        ]
    },
    
    // 登录表单
    login: {
        username: [
            { name: 'required', message: '用户名不能为空' }
        ],
        password: [
            { name: 'required', message: '密码不能为空' }
        ]
    },
    
    // 信访表单
    petition: {
        title: [
            { name: 'required', message: '标题不能为空' },
            { name: 'minLength', value: 5, message: '标题至少5个字符' },
            { name: 'maxLength', value: 100, message: '标题最多100个字符' }
        ],
        content: [
            { name: 'required', message: '内容不能为空' },
            { name: 'minLength', value: 10, message: '内容至少10个字符' },
            { name: 'maxLength', value: 2000, message: '内容最多2000个字符' }
        ],
        petitionerName: [
            { name: 'required', message: '投诉人姓名不能为空' }
        ],
        petitionerPhone: [
            { name: 'required', message: '联系电话不能为空' },
            { name: 'phone', message: '请输入有效的手机号码' }
        ]
    }
};

/**
 * 创建表单验证器的便捷函数
 */
function createFormValidator(form, options = {}) {
    return new FormValidator(form, options);
}

/**
 * 使用预设规则创建验证器
 */
function createFormValidatorWithPreset(form, preset, options = {}) {
    const validator = new FormValidator(form, options);
    
    if (ValidationPresets[preset]) {
        Object.entries(ValidationPresets[preset]).forEach(([fieldName, rules]) => {
            validator.addFieldRule(fieldName, rules);
        });
    }
    
    return validator;
}

// 导出模块
if (typeof module !== 'undefined' && module.exports) {
    module.exports = { 
        FormValidator, 
        ValidationPresets, 
        createFormValidator, 
        createFormValidatorWithPreset 
    };
}

// 全局导出
window.FormValidator = FormValidator;
window.ValidationPresets = ValidationPresets;
window.createFormValidator = createFormValidator;
window.createFormValidatorWithPreset = createFormValidatorWithPreset;